package com.hellowx.qydcdev.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hellowx.qydcdev.dao.GoodsDao;
import com.hellowx.qydcdev.dao.OrderGoodsDao;
import com.hellowx.qydcdev.dao.OrderPayDao;
import com.hellowx.qydcdev.entity.Goods;
import com.hellowx.qydcdev.entity.OrderPay;
import com.hellowx.qydcdev.entity.OrderVO;
import com.hellowx.qydcdev.entity.User;
import com.hellowx.qydcdev.exception.CustomException;
import com.hellowx.qydcdev.exception.CustomExceptionType;
import com.hellowx.qydcdev.service.OrderService;
import com.hellowx.qydcdev.utils.PayUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created on 2022/1/10.
 *
 * @author Hello WX
 */
@Service("orderService")
public class OrderServiceImpl implements OrderService {

    @Resource
    private OrderPayDao orderPayDao;
    @Resource
    private OrderGoodsDao orderGoodsDao;
    @Resource
    private GoodsDao goodsDao;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public long createOrder(String json) {
        try {
            json = URLDecoder.decode(json, "utf-8");
            OrderVO orderVO = JSON.parseObject(json, OrderVO.class);
            OrderPay orderPay = new OrderPay();
            orderPay.setStatus(0);
            orderPay.setTotalPrice(0);
            orderPay.setCustomerId(orderVO.getCustomerId());
            orderPay.setAddressId(orderVO.getAddressId());
            Goods one = new LambdaQueryChainWrapper<>(goodsDao)
                    .eq(Goods::getId, orderVO.orderGoodsList.get(0).getGoodsId())
                    .one();
            orderPay.setBusinessId(one.getBusinessId());
            if (orderVO.orderGoodsList != null) {
                int totalPrice = orderVO.orderGoodsList.stream().mapToInt(goods -> goods.getPrice() * goods.getGoodsNum()).sum();
                orderPay.setTotalPrice(totalPrice);
            }
            orderPayDao.insert(orderPay);
            if (orderPay.getId()>0){
                if (orderVO.orderGoodsList!=null){
                    orderVO.orderGoodsList.forEach(orderGoods -> {
                        orderGoods.setOrderId(orderPay.getId());
                        orderGoodsDao.insert(orderGoods);
                    });
                }
            }
            return orderPay.getId();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return 0;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean toPay(long orderId) {

        OrderPay orderPay = new LambdaQueryChainWrapper<>(orderPayDao)
                .eq(OrderPay::getId, orderId)
                .one();
        if (orderPay==null){
            throw new CustomException(CustomExceptionType.SYSTEM_EXCEPTION,"订单不存在");
        }
        long payNo = PayUtils.toPay(orderId);
        orderPay.setPayNo(payNo);
        orderPay.setStatus(1);
        int rows = orderPayDao.updateById(orderPay);
        return rows>0;
    }

    @Override
    public PageInfo<OrderVO> listOrderByCustomerId(Long customerId, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum,pageSize);
        List<OrderVO> orderVOList = orderPayDao.selectOrderVOByCustomerList(customerId,null,null);
        PageInfo<OrderVO> pageInfo = new PageInfo<OrderVO>(orderVOList);
        return pageInfo;
    }

    @Override
    public PageInfo<OrderVO> listOrderByBusinessId(Long businessId, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum,pageSize);
        List<OrderVO> orderVOList = orderPayDao.selectOrderVOByCustomerList(null,null,businessId);
        PageInfo<OrderVO> pageInfo = new PageInfo<OrderVO>(orderVOList);
        return pageInfo;
    }

    @Override
    public OrderVO getOrderByOrderId(long orderId) {
        List<OrderVO> orderVOList = orderPayDao.selectOrderVOByCustomerList(null, orderId,null);
        if (orderVOList!=null){
            return orderVOList.get(0);
        }
        return null;
    }

    @Override
    public PageInfo<OrderPay> listOrderBySearch(Long orderId, Long payNo, int pageNum, int pageSize, HttpServletRequest request) {
        User loginUser = (User) request.getAttribute("loginUser");
        Long businessId = loginUser.getBusinessId();
        PageHelper.startPage(pageNum,pageSize);
        QueryWrapper<OrderPay> wrapper = new QueryWrapper<>();
        if (businessId!=0L){
            wrapper.eq("business_id",businessId);
        }
        if (orderId != null){
            wrapper.eq("id",orderId);
        }
        if (payNo != null){
            wrapper.eq("pay_no",payNo);
        }
        wrapper.orderByDesc("create_time");
        List<OrderPay> orderPays = orderPayDao.selectList(wrapper);
        return new PageInfo<OrderPay>(orderPays);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String unsubscribe(Long orderId, int status) {
        OrderPay orderPay = new OrderPay();
        orderPay.setId(orderId);
        orderPay.setStatus(status);
        int rows = orderPayDao.updateById(orderPay);
        return rows>0 ? "提交成功" : "修改失败";
    }

    @Override
    public List<Map<String, Object>> variousOrdersPie(HttpServletRequest request) {
        User loginUser = (User) request.getAttribute("loginUser");
        Long businessId = null;
        if (loginUser.getBusinessId()!=0L){
            businessId = loginUser.getBusinessId();
        }
        List<Map<String, Object>> mapList = orderPayDao.countVariousOrders(businessId);
        if (mapList!=null){
            mapList.forEach(map->{
                if (map!=null){
                    switch ((Integer) map.get("status")){
                        case 0:
                            map.put("name","未支付");
                            break;
                        case 1:
                            map.put("name","已支付");
                            break;
                        case 2:
                            map.put("name","退订中");
                            break;
                        case 3:
                            map.put("name","已退订");
                            break;
                        default:
                            break;
                    }
                }
            });
        }
        return mapList;
    }

    @Override
    public Map<String, Object> countOrderByMonth(HttpServletRequest request) {
        User loginUser = (User) request.getAttribute("loginUser");
        Long businessId = null;
        if (loginUser.getBusinessId()!=0L){
            businessId = loginUser.getBusinessId();
        }
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        String dateStr = sdf.format(date);
        return orderPayDao.countOrderByMonth(businessId,dateStr);
    }

    @Override
    public Map<String, Object> countOrderByDay(HttpServletRequest request) {
        User loginUser = (User) request.getAttribute("loginUser");
        Long businessId = null;
        if (loginUser.getBusinessId()!=0L){
            businessId = loginUser.getBusinessId();
        }
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String dateStr = sdf.format(date);
        return orderPayDao.countOrderByDay(businessId,dateStr);
    }

    @Override
    public Map<String, Object> countGoodsOrderTop8(HttpServletRequest request) {
        User loginUser = (User) request.getAttribute("loginUser");
        Long businessId = null;
        if (loginUser.getBusinessId()!=0L){
            businessId = loginUser.getBusinessId();
        }
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        String dateStr = sdf.format(date);
        List<Map<String, Object>> mapList = orderPayDao.countOrderGoodsTop8(businessId,dateStr);
        Map<String, Object> resultMap = new HashMap<>();
        List<String> nameList = new ArrayList<>();
        List<Integer> valueList = new ArrayList<>();
        if (mapList!=null){
            mapList.forEach(map->{
                String goodsName = (String) map.get("goods_name");
                Integer number = ((Long) map.get("number")).intValue();
                nameList.add(goodsName);
                valueList.add(number);
            });
        }
        resultMap.put("nameList",nameList);
        resultMap.put("valueList",valueList);
        return resultMap;
    }
}
